package  systems.lsystem
{
	import com.bit101.components.HUISlider;
	import com.bit101.components.NumericStepper;
	import com.bit101.components.Text;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageDisplayState;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.ui.Keyboard;
	import systems.lsystem.Lsystem;
	
	/**
	 * @author Nicolas Barradeau
	 * http://en.nicoptere.net
	 */
	public class LsystemSample extends Sprite 
	{
		private var ls:Lsystem;
		private var axiom:Text;
		private var rule:Text;
		private var length:HUISlider;
		private var theta:NumericStepper;
		private var delta:NumericStepper;
		private var generations:HUISlider;
		private var sw:int;
		private var sh:int;
		
		public function LsystemSample() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.displayState = StageDisplayState.FULL_SCREEN;
			
			sw = stage.stageWidth;
			sh = stage.stageHeight;
			ls = new Lsystem( 'f', 'f+f-f-f+f', 20, Math.PI, Math.PI * .5 );
			ls.x = sw / 2;
			ls.y = sh / 2;
			addChild( ls );
			
			ls.addEventListener( MouseEvent.MOUSE_UP, dragHandler );
			ls.addEventListener( MouseEvent.MOUSE_DOWN, dragHandler );
			ls.buttonMode = true;
			
			
			stage.addEventListener( KeyboardEvent.KEY_DOWN, keyHandler );
			
			/*
			a: F
			r: F+F-F-F+F
			t: 180
			d: 90
			
			a: f-f-f-f-f
			r: FF-[-F+F+F]+[+F-F-F]
			t: 180
			d: 90
			
			a: F
			r: F+F-F-F+F[F++F--]++
			t: 0
			d: 60
			
			a: f+f+f
			r: F+Ff+f+ff-f-ff
			t: 0
			d: 120
			
			a: Ff-FF--FF+FF
			r: F - F++[F - ff + fffff - ff - f] + F[ +f - F + ] - F - F
			t: 45
			d: 37
			
			a: f+f-f+f-f+f-f+f-f+f-f+f-f+f-f+f
			r: F - F++[F+++++ ff ++ff++ ffff - ff - f] [ff-f-f--]+ F[ +f - F+++++++ + ] - F - F
			t: 0
			d: 12
			*/
			
			
			
			axiom = new Text( this, 10, sh - 100, 'f' ); 
			axiom.height = 20;
			
			rule = new Text( this, 10, sh - 80, 'F+F-F-F+F' );
			rule.height = 50;
			
			length = new HUISlider( this, 10, sh - 30, 'length', changeHandler );
			length.value = 100;
			
			theta = new NumericStepper( this, length.x + length.width + 20, sh - 30, changeHandler );
			theta.maximum = 360;
			theta.value = 0;
			
			delta = new NumericStepper( this, length.x + length.width + 20, sh - 50, changeHandler );
			delta.maximum = 360;
			delta.value = 90;
			
			generations = new HUISlider( this, theta.x + theta.width + 20, sh - 30, 'generations', changeHandler );
			generations.maximum = 5;
			generations.value = 0;
			
			stage.addEventListener( KeyboardEvent.KEY_UP, changeHandler );
			changeHandler( null );
			
		}
		private var current:int = 0;
		private function keyHandler(e:KeyboardEvent):void 
		{
			
			if ( 	e.keyCode != Keyboard.UP 
			&& 		e.keyCode != Keyboard.DOWN ) return;
			
			
			switch( e.keyCode )
			{
				case Keyboard.UP:
				current++;
				break;
				case Keyboard.DOWN:
				current--;
				break;
			}
			if ( current < 0 ) current = 0;
			current %= 5;
			
			var op:int = 0; 
			switch( current )
			{
				case op++:
			
				axiom.text = "F-F-F-F-F";
				rule.text = "F-F++F+F-F-F";
				length.value = 100;
				theta.value = Math.PI / 180;
				delta.value = Math.PI / 180;
				
				break;
				
			
				case op++:
				
				axiom.text = 'f-f-f-f-f';
				rule.text = 'FF-[-F+F+F]+[+F-F-F]';
				length.value = 50;
				theta.value = 180;
				delta.value = 90;
				
				break;
				
				case op++:
				
				axiom.text = "f";
				rule.text = "F+F-F-F+F[F++F--]++";
				length.value = 50;
				theta.value = 0;
				delta.value = 60;
				
				break;
				
				case op++:
				
				axiom.text = "f+f+f";
				rule.text = "F+Ff+f+ff-f-ff";
				length.value = 50;
				theta.value = 0;
				delta.value = 120;
				
				break;
				
				case op++:
				
				axiom.text = "Ff-FF--FF+FF";
				rule.text = "F - F++[F - ff + fffff - ff - f] + F[ +f - F + ] - F - F";
				length.value = 50;
				theta.value = 45;
				delta.value = 37;
				
				break;
			
				case op++:
				
				axiom.text = "f+f-f+f-f+f-f+f-f+f-f+f-f+f-f+f";
				rule.text = "F - F++[F+++++ ff ++ff++ ffff - ff - f] [ff-f-f--]+ F[ +f - F+++++++ + ] - F - F";
				length.value = 50;
				theta.value = 0;
				delta.value = 12;
				
				break;
				
			}
			generations.value = 1;
			changeHandler();
		}
		
		private function dragHandler(e:MouseEvent):void 
		{
			switch( e.type )
			{
				case MouseEvent.MOUSE_UP:
				Sprite( e.target ).stopDrag();
				break;
				
				case MouseEvent.MOUSE_DOWN:
				Sprite( e.target ).startDrag();
				break;
			}
		}
		
		
		private function changeHandler( e:Event = null ):void 
		{
			
			ls.axiom = axiom.text;
			ls.rule = rule.text;
			ls.length = length.value;
			ls.theta = theta.value * Math.PI / 180;
			ls.delta = delta.value * Math.PI / 180;
			
			ls.compute( int( generations.value ) );
			
			ls.render();
			
		}
		
	}

}